package net.loyin.jfinal.plugin;

import java.util.List;

import javax.sql.DataSource;

import org.apache.commons.lang3.StringUtils;

import net.loyin.jfinal.anatation.TableBind;

import com.jfinal.kit.StringKit;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.activerecord.IDataSourceProvider;
import com.jfinal.plugin.activerecord.Model;
/***
 * 自动绑定model与数据库表
 * @author loyin
 *  2012-9-4 上午11:45:09
 */
public class AutoTableBindPlugin extends ActiveRecordPlugin {
	
	private TableNameStyle tableNameStyle;
	
	public AutoTableBindPlugin(DataSource dataSource) {
		super(dataSource);
	}

	public AutoTableBindPlugin(IDataSourceProvider dataSourceProvider, TableNameStyle tableNameStyle) {
		super(dataSourceProvider);
		this.tableNameStyle = tableNameStyle;
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public boolean start() {
		
		try {
			List<Class> modelClasses = ClassSearcher.findClasses( Model.class );
			TableBind tb = null;
			
			for ( Class modelClass : modelClasses ) 
			{
				
				tb = (TableBind) modelClass.getAnnotation( TableBind.class );
				if ( tb == null ) 
				{
					this.addMapping( tableName( modelClass ), modelClass );  // 指定model类和table映射
				} else 
				{
					
					if ( !StringUtils.isBlank( tb.name() ) )
					{
						
						if ( !StringUtils.isBlank( tb.pk() ) )
						{
							this.addMapping( tb.name(), tb.pk(), modelClass );  // 指定model类和table映射,并指定primary key
						} else 
						{
							this.addMapping( tb.name(), modelClass );  // 指定model类和table映射
						}
						
					}
					
				}
			}
			
		} catch (Exception e) {
			e.printStackTrace();
//			throw new RuntimeException(e);
		}
		
		return super.start();
	}

	@Override
	public boolean stop() {
		return super.stop();
	}

	/**
	 * 生成规范的表名称
	 * 
	 * @param clazz
	 * @return
	 */
	private String tableName(Class<?> clazz) {
		
		String tableName = clazz.getSimpleName();  // 数据库表对应model名称
		if ( tableNameStyle == TableNameStyle.UP ) 
		{
			tableName = tableName.toUpperCase();  // 表名称大写
		} else if ( tableNameStyle == TableNameStyle.LOWER ) 
		{
			tableName = tableName.toLowerCase();  // 表名称小写
		} else 
		{
			tableName = StringKit.firstCharToLowerCase( tableName );  // 表名称驼峰命名规则
		}
		
		return tableName;
	}
}
